package com.ukefu.webim.web.handler.apps.workorders;

import static org.elasticsearch.index.query.QueryBuilders.termQuery;

import java.security.NoSuchAlgorithmException;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.snaker.engine.SnakerEngineFacets;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.WorkItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.webim.service.es.WorkOrdersRepository;
import com.ukefu.webim.service.repository.ProcessContentRepository;
import com.ukefu.webim.service.repository.WorkOrderTypeRepository;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.model.WorkOrderType;
import com.ukefu.webim.web.model.WorkOrders;

@Controller
@RequestMapping("/apps/workorder/type")
public class WorkOrderTypeController extends Handler{
	
	@Autowired
	private WorkOrderTypeRepository workOrderTypeRes ;
	
	@Autowired
	private WorkOrdersRepository workOrdersRes ;
	
	@Autowired
	private ProcessContentRepository processContentRes ;
	
	@Autowired
	private SnakerEngineFacets facets;
	
    @RequestMapping("/index")
    @Menu(type = "bpm" , subtype = "type" , access = false)
    public ModelAndView index(ModelMap map , HttpServletRequest request) {
    	countWorkOrder(map, request);
    	map.addAttribute("workOrderTypeList", workOrderTypeRes.findByOrgi(super.getOrgi(request), new PageRequest(super.getP(request), super.getPs(request), Sort.Direction.DESC, new String[] { "createtime" }))) ;
    	map.addAttribute("processContentList", processContentRes.findByProcesstypeAndOrgi(UKDataContext.ProcessType.WORKORDER.toString(), super.getOrgi(request))) ;
    	return request(super.createAppsTempletResponse("/apps/business/workordertype/index"));
    }
    
    
    @RequestMapping("/add")
    @Menu(type = "bpm" , subtype = "type" , access = false )
    public ModelAndView add(ModelMap map , HttpServletRequest request) {
    	map.addAttribute("processContentList", processContentRes.findByProcesstypeAndOrgi(UKDataContext.ProcessType.WORKORDER.toString(), super.getOrgi(request))) ;
        return request(super.createRequestPageTempletResponse("/apps/business/workordertype/add"));
    }
    
    @RequestMapping("/save")
    @Menu(type = "bpm" , subtype = "type" , access = false)
    public ModelAndView save(HttpServletRequest request ,@Valid WorkOrderType workOrderType) throws NoSuchAlgorithmException {
    	workOrderType.setOrgi(super.getOrgi(request));
    	workOrderType.setCreater(super.getUser(request).getId());
    	workOrderType.setCreatetime(new Date());
    	workOrderTypeRes.save(workOrderType) ;
    	return request(super.createRequestPageTempletResponse("redirect:/apps/workorder/type/index.html"));
    }
    
    @RequestMapping("/update")
    @Menu(type = "bpm" , subtype = "type" , access = false)
    public ModelAndView update(HttpServletRequest request ,@Valid WorkOrderType workOrderType) throws NoSuchAlgorithmException {
    	WorkOrderType oldProcessType = workOrderTypeRes.findByIdAndOrgi(workOrderType.getId(), super.getOrgi(request)) ;
    	if(oldProcessType!=null){
    		workOrderType.setOrgi(super.getOrgi(request));
        	workOrderType.setCreater(super.getUser(request).getId());
        	workOrderType.setCreatetime(oldProcessType.getCreatetime());
        	workOrderTypeRes.save(workOrderType) ;
    	}
    	return request(super.createRequestPageTempletResponse("redirect:/apps/workorder/type/index.html"));
    }
    
    @RequestMapping("/delete")
    @Menu(type = "bpm" , subtype = "type")
    public ModelAndView delete(ModelMap map , HttpServletRequest request , @Valid String id) {
    	if(!StringUtils.isBlank(id)){
    		workOrderTypeRes.delete(id);
    	}
        return request(super.createRequestPageTempletResponse("redirect:/apps/workorder/type/index.html"));
    }
    
    @RequestMapping("/edit")
    @Menu(type = "bpm" , subtype = "type" , access = false )
    public ModelAndView edit(ModelMap map , HttpServletRequest request , @Valid String id) {
    	map.addAttribute( "workOrderType" , workOrderTypeRes.findByIdAndOrgi(id,super.getOrgi(request))) ;
    	map.addAttribute("processContentList", processContentRes.findByProcesstypeAndOrgi(UKDataContext.ProcessType.WORKORDER.toString(), super.getOrgi(request))) ;
        return request(super.createRequestPageTempletResponse("/apps/business/workordertype/edit"));
    }
    public void countWorkOrder(ModelMap map , HttpServletRequest request) {
    	BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	BoolQueryBuilder myBuilder = QueryBuilders.boolQuery();
    	myBuilder.must(termQuery("creater" , super.getUser(request).getId())) ;
    	boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request))) ;
    	boolQueryBuilder.must(myBuilder) ;
    	
    	Page<WorkOrders> my = workOrdersRes.countById(boolQueryBuilder, null, false, null , 1, super.getPs(request),null) ;
    	
    	boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	myBuilder = QueryBuilders.boolQuery();
    	myBuilder.must(termQuery("accuser" , super.getUser(request).getId())) ;
    	boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request))) ;
    	boolQueryBuilder.must(myBuilder) ;
    	   	
    	Page<WorkOrders> waite = workOrdersRes.countById(boolQueryBuilder, null, false, null , 1, super.getPs(request),null) ;
    	
    	
    	boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	myBuilder = QueryBuilders.boolQuery();
    	boolQueryBuilder.must(termQuery("assigned" , false)) ;
    	
    	boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request))) ;
    	boolQueryBuilder.must(myBuilder) ;
    	
    	Page<WorkOrders> notassigned = workOrdersRes.countById(boolQueryBuilder, null, false, null , 1, super.getPs(request),null) ;
    	
    	boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	boolQueryBuilder.mustNot(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request))) ;
    	Page<WorkOrders> fav = workOrdersRes.findByCreater(boolQueryBuilder, true , false, null, super.getUser(request).getId(),  new PageRequest(1, super.getPs(request))) ;
 
    	boolQueryBuilder = QueryBuilders.boolQuery();
    	
    	myBuilder = QueryBuilders.boolQuery();
    	
    	boolQueryBuilder.must(termQuery("status" , UKDataContext.WORKORDERS_CLOSED_STATUS)) ;
    	boolQueryBuilder.must(termQuery("orgi" , super.getOrgi(request))) ;
    	boolQueryBuilder.must(myBuilder) ;
    	Page<WorkOrders> closed = workOrdersRes.countById(boolQueryBuilder, null, false, null , 1, super.getPs(request),null) ;
    	
    	org.snaker.engine.access.Page<WorkItem> wfpage = new org.snaker.engine.access.Page<WorkItem>(super.getPs(request));
		wfpage.setPageNo(1);
		wfpage.setPageSize(1);
		facets.getEngine().query().getWorkItems(wfpage, new QueryFilter().setProcessType(UKDataContext.BpmType.WORKORDERS.toString()).setOperators(new String[]{super.getUser(request).getId() , super.getUser(request).getOrgan()})) ;

		map.addAttribute("workflow", wfpage.getTotalCount()) ;
    	map.addAttribute("mycount", my.getTotalElements()) ;
    	map.addAttribute("wait", waite.getTotalElements()) ;
    	map.addAttribute("notassigned", notassigned.getTotalElements()) ;
    	map.addAttribute("fav", fav.getTotalElements()) ;
    	map.addAttribute("closed", closed.getTotalElements()) ;
    }
}